<template>
  <view>
    <view class="table-right-wrapper">
      <scroll-view
        scroll-x
        style="width: 100%"
        :scrollLeft="scrollLeft.date.num"
        :scroll-with-animation="false"
        @scroll="onScroll($event, 'date')"
      >
        <view class="header">
          <view
            class="date-item"
            v-for="item in CarStockState.dayList"
            :key="item.fullDate"
            :class="{ today: item.today }"
            :style="{ width: CarStockState.dayPx + 'px' }"
          >
            周{{ item.week }}
            <view v-if="item.today" class="day">今</view>
            <view v-else class="day">{{ item.date }}</view>
          </view>
        </view>
      </scroll-view>
      <view class="body">
        <scroll-view
          scroll-x
          scroll-y
          :style="{ maxHeight: maxHeight }"
          style="width: 100%"
          :scroll-top="scrollTop.num"
          :scroll-left="scrollLeft.car.num"
          :scroll-with-animation="false"
          @scroll="onScroll($event, 'car')"
        >
          <!-- 车格子 -->
          <view class="place-section before" :style="{ width: '100%', height: stockData.beforePlaceHeight + 'px' }"></view>
          <view class="right-tr" :class="{ full: car.isCarModel }" v-for="car in stockData.visibleList" :key="car.key">
            <!-- 车型 -->
            <view class="modelName" :style="{ left: scrollLeft.bottom + 'px' }" v-if="car.isCarModel">
              <ve-icon name="car" width="32" height="32" style="margin-top: -1px" />
              {{ car.modelName }}
            </view>
            <template v-else>
              <!-- 日期空白格子 -->
              <view
                @click="handleDayClick(car, item.fullDate)"
                :style="{ width: CarStockState.dayPx + 'px' }"
                class="right-td"
                v-for="item in CarStockState.dayList"
                :key="item.date"
              ></view>
            </template>
            <!-- 占用条 -->
            <template v-if="loading == false">
              <FlyBar :data="bar" v-for="bar in car.bars" :key="bar.id" />
            </template>
          </view>
          <view class="right-tr full">
            <view class="bottom-wrap" v-if="stockData.visibleList?.length" :style="{ left: scrollLeft.bottom + 'px' }">
              <view class="line"></view>
              <view>已经到底啦</view>
              <view class="line"></view
            ></view>
          </view>
          <view class="place-section after" :style="{ width: '100%', height: stockData.afterPlaceHeight + 'px' }"></view>
        </scroll-view>
      </view>
    </view>
    <!-- picker操作 -->
    <HandlePicker v-model="handleVisible" @ok="onHandle" />
    <!-- 占用列表弹框 -->
    <ve-modal closable v-model="visible">
      <FlyBarCont :selectable="selectable" :data="activedOrder" @ok="handleOk" />
      <template #footer>
        <HandleBtns v-if="platoonCarAble && isDayFull == false" @ok="onHandle" />
      </template>
    </ve-modal>
  </view>
</template>

<script lang="ts">
  import { ref, watch, reactive, inject } from 'vue'
  import dayjs from 'dayjs'
  import FlyBar from './fly-bar.vue'
  import FlyBarCont from './fly-bar-cont.vue'
  import HandlePicker from './widget/handle-picker.vue'
  import HandleBtns from './widget/handle-btns.vue'

  export default {
    components: {
      FlyBar,
      FlyBarCont,
      HandlePicker,
      HandleBtns,
    },
    props: {
      selectable: Boolean,
      stockData: Object,
      platoonCarAble: Boolean,
      scrollTopRecorder: Object,
      loading: Boolean,
      maxHeight: String,
    },
    emits: ['update:dayIndex', 'onScroll'],
    setup(props, { emit }) {
      const CarStockState = inject('CarStockState')
      // 底部操作开关
      const handleVisible = ref(false)
      const isDayFull = ref(false)
      // 点击day处理
      const toPlatoonCarParam = ref()
      // 点击day处理，以为点击以天为范围，需要展示范围内所有的占用
      const handleDayClick = (car: any, date: string) => {
        // 初始化
        isDayFull.value = false
        toPlatoonCarParam.value = [car, date]
        const carUseDate = car.bars
        const dayStart = dayjs(date + ' 00:00:00')
        const dayEnd = dayjs(date + ' 23:59:59')
        if (!carUseDate || carUseDate.length == 0) {
          // 去操作
          if (props.selectable) return
          handleVisible.value = true
          return
        }
        const timeList: any = []
        // 整理数据，将冲突的数据拆分出来，或者增加冲突标签
        const newCarUseDate = []
        carUseDate.forEach((item: any) => {
          if (item.type == 5) {
            // 补充冲突标签
            item.repeatList?.forEach((repeatItem: any) => {
              // 不在当天
              if (dayStart.isAfter(item.toTime) || dayEnd.isBefore(item.fromTime)) {
                return
              }
              const raw_data = carUseDate.find((it: any) => it.id == repeatItem.id)
              if (raw_data) {
                raw_data.typeSet.push(5)
              } else {
                if (newCarUseDate.findIndex((it: any) => it.id == repeatItem.id) == -1) {
                  repeatItem.fromTime = item.fromTime
                  repeatItem.toTime = item.toTime
                  repeatItem.typeSet.push(5)
                  newCarUseDate.push(repeatItem)
                }
              }
            })
            return
          }
          newCarUseDate.push(item)
        })
        newCarUseDate.forEach((item: any) => {
          let useItem
          // 不在当天
          if (dayStart.isAfter(item.toTime) || dayEnd.isBefore(item.fromTime)) {
            return
          }
          // 包括当天
          if (dayjs_isSameOrAfter(dayStart, item.fromTime) && dayjs_isSameOrBefore(dayEnd, item.endTime)) {
            useItem = {
              start: dayStart.valueOf(),
              end: dayEnd.valueOf(),
              data: item,
            }
            isDayFull.value = true
          }
          // 当天之中
          useItem = {
            start: Math.max(dayStart.valueOf(), new Date(item.fromTime).getTime()),
            end: Math.min(dayEnd.valueOf(), new Date(item.toTime).getTime()),
            data: item,
          }
          timeList.push(useItem)
        })
        // 有沾满一天的订单的跳过
        if (isDayFull.value == false) {
          // 判断当天的bar 是否占满一整天
          calcIsFullDay(timeList, dayStart.valueOf(), dayEnd.valueOf())
        }
        if (timeList.length == 0) {
          // 去操作
          if (props.selectable) return
          handleVisible.value = true
          return
        }
        // 打开订单占用弹框
        openOrderModal({ list: timeList.map((it: any) => it.data) })
      }

      // 去排车
      const toPlatoonCarFn = () => {
        toPlatoonCar(toPlatoonCarParam.value[0], toPlatoonCarParam.value[1])
      }

      // 判断当天的bar 是否占满一整天
      const calcIsFullDay = (timeList: any, s_timer: number, e_timer: number) => {
        // 开始是否顶点
        const start_point = timeList.find((it: any) => it.start == s_timer)
        if (!start_point) {
          return
        }
        // 结束是否顶点
        const end_point = timeList.find((it: any) => it.end == e_timer)
        if (!end_point) {
          return
        }
        for (let index = 0; index < timeList.length; index++) {
          const it = timeList[index]
          let left_point = timeList.find((it1: any, tIndex: number) => {
            return tIndex != index && it.start >= it1.start && it.start <= it1.end
          })
          if (it.start == s_timer) {
            left_point = true
          }
          let right_point = timeList.find((it1: any, tIndex: number) => {
            return tIndex != index && it.end >= it1.start && it.end <= it1.end
          })
          if (it.end == e_timer) {
            right_point = true
          }
          if (!left_point || !right_point) return
        }
        isDayFull.value = true
      }

      const dayjs_isSameOrAfter = (dayjsob_start: dayjs.Dayjs, end: string) => {
        return dayjsob_start.isSame(end) || dayjsob_start.isAfter(end)
      }
      const dayjs_isSameOrBefore = (dayjsob_start: dayjs.Dayjs, end: string) => {
        return dayjsob_start.isSame(end) || dayjsob_start.isBefore(end)
      }

      // 排车
      const toPlatoonCar = (car: any, date: string) => {
        if (props.platoonCarAble == false) return
        const options = JSON.stringify({
          startDate: date,
          carId: car.carId,
          licenseNo: car.licenseNo,
          carModelId: car.modelId,
          modelName: car.modelName,
        })
        uni.navigateTo({
          url: '/pages/asset/stock/car-stock/platoon-car?info=' + options,
        })
      }
      // 查看占用信息
      const visible = ref(false)
      const activedOrder = ref()
      const openOrderModal = (record: any) => {
        activedOrder.value = record
        visible.value = true
      }
      // 滚动left值
      const scrollLeft = reactive({
        // 日期
        date: {
          flag: false,
          timer: 0,
          num: 0,
        },
        // 车辆
        car: {
          flag: false,
          timer: 0,
          num: 0,
        },
        bottom: 0,
      })
      let cacheDayIndex = 0
      // 滚动top值
      const scrollTop = reactive({
        flag: false,
        timer: 0,
        num: 0,
      })
      const onScroll = (event: any, type: string) => {
        // 左右滚动
        if (event.detail.deltaX != 0) {
          scrollLeft.bottom = event.detail.scrollLeft
          // 车辆滚动
          if (type == 'car' && !scrollLeft.car.flag) {
            scrollLeft.date.num = event.detail.scrollLeft
            scrollLeft.date.flag = true

            if (scrollLeft.date.timer) {
              clearTimeout(scrollLeft.date.timer)
              scrollLeft.date.timer = 0
            }
            scrollLeft.date.timer = setTimeout(() => {
              scrollLeft.date.flag = false
            }, 500)
            updateCacheDayIndex(event)
          }
          if (type == 'date' && !scrollLeft.date.flag) {
            scrollLeft.car.num = event.detail.scrollLeft
            scrollLeft.car.flag = true

            if (scrollLeft.car.timer) {
              clearTimeout(scrollLeft.car.timer)
              scrollLeft.car.timer = 0
            }
            scrollLeft.car.timer = setTimeout(() => {
              scrollLeft.car.flag = false
            }, 500)
            updateCacheDayIndex(event)
          }
        }
        // 上下滚动
        if (event.detail.deltaY != 0) {
          if (!scrollTop.flag) {
            emit('onScroll', event.detail.scrollTop)
          }
        }
      }
      watch(
        () => props.scrollTopRecorder,
        ({ triggerType, top }: Record<string, any>) => {
          if (triggerType == 'left') {
            scrollTop.flag = true
            scrollTop.num = top
            if (scrollTop.timer) {
              clearTimeout(scrollTop.timer)
              scrollTop.timer = 0
            }
            scrollTop.timer = setTimeout(() => {
              scrollTop.flag = false
            }, 500)
          }
        },
        { deep: true },
      )
      // 重置滚动位置
      const resetScrollPosition = () => {
        // 需手动设置为 -1，再设置为0，否则可能不生效
        scrollTop.num = -1
        scrollLeft.date.num = -1
        scrollLeft.car.num = -1
        setTimeout(() => {
          scrollTop.num = 0
          scrollLeft.date.num = 0
          scrollLeft.car.num = 0
        }, 0)
      }
      // 更新缓存的日期索引
      const updateCacheDayIndex = (event: any) => {
        const actived_day_index = Math.floor(event.detail.scrollLeft / CarStockState.dayPx)
        if (cacheDayIndex != actived_day_index) {
          emit('update:dayIndex', actived_day_index)
          cacheDayIndex == actived_day_index
        }
      }
      // 操作
      const onHandle = (event: string) => {
        // 关闭弹框和picker
        handleVisible.value = false
        visible.value = false
        // 取出选择车辆作为参数
        const car = toPlatoonCarParam.value[0]
        const params = `?carId=${car.carId}&licenseNo=${car.licenseNo}&modelName=${car.modelName}`
        if (event == 'platoonCar') {
          toPlatoonCarFn()
        } else if (event == 'addTempUse') {
          uni.navigateTo({
            url: '/pages/asset/stock/car-stock/temp-use' + params,
          })
        } else if (event == 'removeTempUse') {
          uni.navigateTo({
            url: '/pages/asset/stock/car-stock/remove-temp-use' + params,
          })
        }
      }

      // 操作完成
      const handleOk = () => {
        visible.value = false
        uni.$emit('carStock:loadData')
      }

      return {
        visible,
        handleVisible,
        activedOrder,
        isDayFull,
        scrollTop,
        scrollLeft,
        CarStockState,
        onScroll,
        handleDayClick,
        toPlatoonCarFn,
        handleOk,
        onHandle,
        resetScrollPosition,
      }
    },
  }
</script>

<style lang="less" scoped>
  @TableLeftWidth: 110px;
  @tdWidth: 48px;
  @tdHeight: 36px;
  @theadHeight: 48px;

  .table-right-wrapper {
    position: relative;
    z-index: 8;
    .header {
      position: relative;
      z-index: 10;
      height: @theadHeight;
      display: flex;
      flex-wrap: nowrap;
      margin-left: @TableLeftWidth;
      .date-item {
        flex-shrink: 0;
        width: @tdWidth;
        background: #f4f4f4;
        padding-top: 10rpx;
        // 字
        text-align: center;
        font-size: 24rpx;
        font-weight: 400;
        color: #000000;
        line-height: 44rpx;
        border-right: 1px solid #e3e4e6;
        border-bottom: 1px solid #e3e4e6;
        .day {
          line-height: 1;
          font-size: 22rpx;
        }

        &.today {
          background: #2a64f6;
          color: #ffffff;
        }
      }
    }
    .body {
      position: relative;
      z-index: 10;
      .right-tr {
        position: relative;
        display: flex;
        flex-wrap: nowrap;
        height: @tdHeight;
        // width: 100%;
        margin-left: @TableLeftWidth;

        &.full {
          margin-left: 0;
          background: #f7f8fa;
        }

        .right-td {
          flex-shrink: 0;
          height: @tdHeight;
          width: @tdWidth;
          background: #ffffff;
          border-right: 1px solid #e3e4e6;
          border-bottom: 1px solid #e3e4e6;
          &.clash-td {
            border-right: 1px solid #fff;
          }
        }
        .modelName {
          position: absolute;
          left: 0;
          z-index: 99;
          font-weight: 400;
          font-size: 24rpx;
          color: #2a64f6;
          line-height: @tdHeight;
          width: 100%;
          height: 100%;
          padding-left: 18rpx;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          border-bottom: 1px solid #e3e4e6;
        }
      }
    }
  }

  :deep(.uni-scroll-view, .uni-scroll-view-content) {
    overscroll-behavior: none;
  }
  :deep(.uni-scroll-view-content) {
    overscroll-behavior: none;
  }

  .place-section {
    position: relative;
    width: 100%;
    background: #f7f8fa;
  }

  .bottom-wrap {
    position: absolute;
    width: 100%;
    height: @tdHeight;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24rpx;
    color: #9ea5bb;

    .line {
      width: 60rpx;
      height: 1px;
      background: #e3e4e6;
      margin: 0 20rpx;
    }
  }
</style>
